package com.seven.thread;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author sevenDay
 * @classname ThreadMonitor
 * @description: 描述TODO
 * @date 2018/7/16
 */
public class ThreadMonitor implements Runnable {

    private static Logger LOGGER = LoggerFactory.getLogger(ThreadMonitor.class);

    public static volatile boolean show=true;

    private  ThreadPoolExecutor pool = null;

    private ConcurrentHashMap<String,Object> taskContainer;

    public  ThreadMonitor ( ThreadPoolExecutor pool,ConcurrentHashMap<String,Object> taskContainer){
            this.pool = pool;
            this.taskContainer = taskContainer;
    }

    @Override
    public void run() {
        while (show){
            int size =  pool.getQueue().size();
            int lifeSize = pool.getActiveCount();
            long completedTaskCount = pool.getCompletedTaskCount();
            long taskCount = pool.getTaskCount();

            try {
                LOGGER.info("当前排队数目 {} ,当前活动线程 {} , 执行完成线程数目 {} ," +
                        "总线程数(排队线程数 + 活动线程数 +  执行完成线程数): {} ",size,lifeSize,completedTaskCount,taskCount);
                showTaskDetail();
                Thread.sleep(3000);
            } catch (InterruptedException e) {

                e.printStackTrace();

            }
        }


    }

    /**
     * 遍历和打印单个任务的详情
     */
    private void showTaskDetail(){
        //获取当前执行的时间
        long currentTime = System.nanoTime();
        for (Map.Entry<String, Object> str : taskContainer.entrySet()) {
            String key = str.getKey();
            Object obj =  str.getValue();

            //线程执行状态[没有执行，执行中，执行完成]，线程执行的时间，线程的taskId，线程的执行的taskName，

            if (obj instanceof SevenThread){
               /* if (LOGGER.isDebugEnabled()){
                    LOGGER.debug("线程类别是 SevenThread");
                }*/
                SevenThread sevenThread = (SevenThread)obj;
                long  startTime =  sevenThread.getStartTime();
                int state = getThreadState(currentTime,sevenThread.getStartTime(),sevenThread.getEndTime());
                if (state==2){
                    //执行完成
                     showTaskInfoMessage(sevenThread.getTaskId(),sevenThread.getTaskName(),sevenThread.getEndTime()-sevenThread.getStartTime(),state);
                }else if (state==1){
                    //执行中
                    showTaskInfoMessage(sevenThread.getTaskId(),sevenThread.getTaskName(),currentTime-sevenThread.getStartTime(),state);
                }

            }else if ( obj instanceof SevenRunnable){
                SevenRunnable sevenRunnable = (SevenRunnable)obj;
                long  startTime =  sevenRunnable.getStartTime();
                int state = getThreadState(currentTime,sevenRunnable.getStartTime(),sevenRunnable.getEndTime());
                if (state==2){
                    //执行完成
                    showTaskInfoMessage(sevenRunnable.getTaskId(),sevenRunnable.getTaskName(),sevenRunnable.getEndTime()-sevenRunnable.getStartTime(),state);
                }else if (state==1){
                    //执行中
                    showTaskInfoMessage(sevenRunnable.getTaskId(),sevenRunnable.getTaskName(),currentTime-sevenRunnable.getStartTime(),state);
                }

            }else if (obj instanceof SevenCallable){
               /* if (LOGGER.isDebugEnabled()){
                    LOGGER.debug("线程类别是 SevenCallable");
                }*/
                SevenCallable sevenCallable = (SevenCallable)obj;
                long  startTime =  sevenCallable.getStartTime();
                int state = getThreadState(currentTime,sevenCallable.getStartTime(),sevenCallable.getEndTime());
                if (state==2){
                    //执行完成
                    showTaskInfoMessage(sevenCallable.getTaskId(),sevenCallable.getTaskName(),sevenCallable.getEndTime()-sevenCallable.getStartTime(),state);
                }else if (state==1){
                    //执行中
                    showTaskInfoMessage(sevenCallable.getTaskId(),sevenCallable.getTaskName(),currentTime-sevenCallable.getStartTime(),state);
                }

            }

        }
    }

    /**
     * 获取线程执行状态
     * @param currentTime 当前时间
     * @param startTime 开始执行时间
     * @param endTime  开始结束时间
     * @return int 0 没有执行，1执行中，2 执行完成，-1 未知情况
     */
    private int getThreadState(long currentTime,long startTime,long endTime){
                if (startTime==0){
                    //没有执行
                    return 0;
                }
                if (endTime==0){
                    //执行中
                    return 1;
                }if (startTime!=0&&endTime!=0){
                    if (endTime<currentTime){
                        //执行完成
                        return 2;
                    }else{
                        return -1;
                    }
        }
        return -1;
    }

    /**
     *
     * @param state
     */
    /**
     * 打印线程的信息和执行状态 （一毫秒=1000000纳秒）
     * @param taskId 任务Id
     * @param taskName 任务名称
     * @param time 执行任务时间
     * @param state int 0 没有执行，1执行中，2 执行完成，-1 未知情况
     */
    private void  showTaskInfoMessage(int taskId,String taskName,long time,int state){
        switch (state){
            case 0:LOGGER.info("任务taskId:{} 任务名称:{} 任务执行时间:{}ms 执行状态:{}",taskId,taskName,time/1000000,"没有执行");break;
            case 1:LOGGER.info("任务taskId:{} 任务名称:{} 任务执行时间:{}ms 执行状态:{}",taskId,taskName,time/1000000,"执行中");break;
            case 2:LOGGER.info("任务taskId:{} 任务名称:{} 任务执行时间:{}ms 执行状态:{}",taskId,taskName,time/1000000,"执行完成");break;
            case -1:LOGGER.info("任务taskId:{} 任务名称:{} 任务执行时间:{}ms 执行状态:{}",taskId,taskName,time/1000000,"未知情况");break;
            default:LOGGER.info("任务taskId:{} 任务名称:{} 任务执行时间:{}ms 执行状态:{}",taskId,taskName,time/1000000,"未知情况错误");LOGGER.error("出现未知情况的错误....");break;
        }
    }
}
